{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Booleans: Precedence and Short-Circuiting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True or True and False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "this is equivalent, because of ``and`` having higer precedence than ``or``, to:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True or (True and False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is not the same as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(True or True) and False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Short-Circuiting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a is at least double b\n"
     ]
    }
   ],
   "source": [
    "a = 10\n",
    "b = 2\n",
    "\n",
    "if a/b > 2:\n",
    "    print('a is at least double b')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-12-98ac73a1accd>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mif\u001b[0m \u001b[0ma\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0mb\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      5\u001b[0m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'a is at least double b'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
     ]
    }
   ],
   "source": [
    "a = 10\n",
    "b = 0\n",
    "\n",
    "if a/b > 2:\n",
    "    print('a is at least double b')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 10\n",
    "b = 0\n",
    "\n",
    "if b and a/b > 2:\n",
    "    print('a is at least double b')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Can also be useful to deal with null or empty strings in a database:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on module string:\n",
      "\n",
      "NAME\n",
      "    string - A collection of string constants.\n",
      "\n",
      "DESCRIPTION\n",
      "    Public module variables:\n",
      "    \n",
      "    whitespace -- a string containing all ASCII whitespace\n",
      "    ascii_lowercase -- a string containing all ASCII lowercase letters\n",
      "    ascii_uppercase -- a string containing all ASCII uppercase letters\n",
      "    ascii_letters -- a string containing all ASCII letters\n",
      "    digits -- a string containing all ASCII decimal digits\n",
      "    hexdigits -- a string containing all ASCII hexadecimal digits\n",
      "    octdigits -- a string containing all ASCII octal digits\n",
      "    punctuation -- a string containing all ASCII punctuation characters\n",
      "    printable -- a string containing all ASCII characters considered printable\n",
      "\n",
      "CLASSES\n",
      "    builtins.object\n",
      "        Formatter\n",
      "        Template\n",
      "    \n",
      "    class Formatter(builtins.object)\n",
      "     |  Methods defined here:\n",
      "     |  \n",
      "     |  check_unused_args(self, used_args, args, kwargs)\n",
      "     |  \n",
      "     |  convert_field(self, value, conversion)\n",
      "     |  \n",
      "     |  format(*args, **kwargs)\n",
      "     |  \n",
      "     |  format_field(self, value, format_spec)\n",
      "     |  \n",
      "     |  get_field(self, field_name, args, kwargs)\n",
      "     |      # given a field_name, find the object it references.\n",
      "     |      #  field_name:   the field being looked up, e.g. \"0.name\"\n",
      "     |      #                 or \"lookup[3]\"\n",
      "     |      #  used_args:    a set of which args have been used\n",
      "     |      #  args, kwargs: as passed in to vformat\n",
      "     |  \n",
      "     |  get_value(self, key, args, kwargs)\n",
      "     |  \n",
      "     |  parse(self, format_string)\n",
      "     |      # returns an iterable that contains tuples of the form:\n",
      "     |      # (literal_text, field_name, format_spec, conversion)\n",
      "     |      # literal_text can be zero length\n",
      "     |      # field_name can be None, in which case there's no\n",
      "     |      #  object to format and output\n",
      "     |      # if field_name is not None, it is looked up, formatted\n",
      "     |      #  with format_spec and conversion and then used\n",
      "     |  \n",
      "     |  vformat(self, format_string, args, kwargs)\n",
      "     |  \n",
      "     |  ----------------------------------------------------------------------\n",
      "     |  Data descriptors defined here:\n",
      "     |  \n",
      "     |  __dict__\n",
      "     |      dictionary for instance variables (if defined)\n",
      "     |  \n",
      "     |  __weakref__\n",
      "     |      list of weak references to the object (if defined)\n",
      "    \n",
      "    class Template(builtins.object)\n",
      "     |  A string class for supporting $-substitutions.\n",
      "     |  \n",
      "     |  Methods defined here:\n",
      "     |  \n",
      "     |  __init__(self, template)\n",
      "     |      Initialize self.  See help(type(self)) for accurate signature.\n",
      "     |  \n",
      "     |  safe_substitute(*args, **kws)\n",
      "     |  \n",
      "     |  substitute(*args, **kws)\n",
      "     |  \n",
      "     |  ----------------------------------------------------------------------\n",
      "     |  Data descriptors defined here:\n",
      "     |  \n",
      "     |  __dict__\n",
      "     |      dictionary for instance variables (if defined)\n",
      "     |  \n",
      "     |  __weakref__\n",
      "     |      list of weak references to the object (if defined)\n",
      "     |  \n",
      "     |  ----------------------------------------------------------------------\n",
      "     |  Data and other attributes defined here:\n",
      "     |  \n",
      "     |  delimiter = '$'\n",
      "     |  \n",
      "     |  flags = <RegexFlag.IGNORECASE: 2>\n",
      "     |  \n",
      "     |  idpattern = '[_a-z][_a-z0-9]*'\n",
      "     |  \n",
      "     |  pattern = re.compile('\\n    \\\\$(?:\\n      (?P<escaped>\\\\$)..._a-z][_a-...\n",
      "\n",
      "FUNCTIONS\n",
      "    capwords(s, sep=None)\n",
      "        capwords(s [,sep]) -> string\n",
      "        \n",
      "        Split the argument into words using split, capitalize each\n",
      "        word using capitalize, and join the capitalized words using\n",
      "        join.  If the optional second argument sep is absent or None,\n",
      "        runs of whitespace characters are replaced by a single space\n",
      "        and leading and trailing whitespace are removed, otherwise\n",
      "        sep is used to split and join the words.\n",
      "\n",
      "DATA\n",
      "    __all__ = ['ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'cap...\n",
      "    ascii_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'\n",
      "    ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'\n",
      "    ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n",
      "    digits = '0123456789'\n",
      "    hexdigits = '0123456789abcdefABCDEF'\n",
      "    octdigits = '01234567'\n",
      "    printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU...\n",
      "    punctuation = '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'\n",
      "    whitespace = ' \\t\\n\\r\\x0b\\x0c'\n",
      "\n",
      "FILE\n",
      "    c:\\users\\fbapt\\anaconda3\\envs\\deepdive\\lib\\string.py\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(string)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0123456789'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string.digits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string.ascii_letters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "string index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-19-b6d1fe6f1f39>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mname\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m''\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mif\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mstring\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdigits\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Name cannot start with a digit!'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mIndexError\u001b[0m: string index out of range"
     ]
    }
   ],
   "source": [
    "name = ''\n",
    "if name[0] in string.digits:\n",
    "    print('Name cannot start with a digit!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "name = ''\n",
    "if name and name[0] in string.digits:\n",
    "    print('Name cannot start with a digit!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "name = None\n",
    "if name and name[0] in string.digits:\n",
    "    print('Name cannot start with a digit!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "name = 'Bob'\n",
    "if name and name[0] in string.digits:\n",
    "    print('Name cannot start with a digit!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name cannot start with a digit!\n"
     ]
    }
   ],
   "source": [
    "name = '1Bob'\n",
    "if name and name[0] in string.digits:\n",
    "    print('Name cannot start with a digit!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
